package com.ruicar.afs.cloud.channel.online.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opencsv.CSVReader;
import com.ruicar.afs.cloud.channel.channelworkflow.entity.WorkTaskAssign;
import com.ruicar.afs.cloud.channel.channelworkflow.entity.WorkTaskDetail;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskApproveRecordService;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskAssignService;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskDetailService;
import com.ruicar.afs.cloud.channel.common.enums.ChannelAfsFlowEnum;
import com.ruicar.afs.cloud.channel.common.feign.ChannelUseCaseService;
import com.ruicar.afs.cloud.channel.common.until.ChannelConfig;
import com.ruicar.afs.cloud.channel.online.condition.ArchivesLogInfoCondition;
import com.ruicar.afs.cloud.channel.online.condition.QuotaCondition;
import com.ruicar.afs.cloud.channel.online.entity.ChannelBaseInfoTemp;
import com.ruicar.afs.cloud.channel.online.entity.ChannelQuotaInfoTemp;
import com.ruicar.afs.cloud.channel.online.entity.ChannelRiskInfoTemp;
import com.ruicar.afs.cloud.channel.online.mapper.ChannelQuotaInfoMapper;
import com.ruicar.afs.cloud.channel.online.service.ChannelArchivesInfoService;
import com.ruicar.afs.cloud.channel.online.service.ChannelOnlineService;
import com.ruicar.afs.cloud.channel.online.service.ChannelQuotaInfoService;
import com.ruicar.afs.cloud.channel.online.service.ChannelRiskInfoService;
import com.ruicar.afs.cloud.channel.online.vo.ChannelQuotaInfoVo;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.uid.UidGenerator;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.StartFlowRequest;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ruicar.afs.cloud.channel.online.untils.ChannelOnlineConstants.*;

/**
 * @author mingzhi.li
 * @version 1.0
 * @describe 渠道保证金临时表维护
 * @date 2020/05/25 11：20
 */
@Service
public class ChannelQuotaInfoServiceImpl extends ServiceImpl<ChannelQuotaInfoMapper, ChannelQuotaInfoTemp> implements ChannelQuotaInfoService {

    @Autowired
    private ChannelArchivesInfoService channelArchivesInfoService;
    @Autowired
    private ChannelRiskInfoService channelRiskInfoService;
    @Autowired
    private ChannelConfig channelConfig;
    @Autowired
    private ChannelUseCaseService channelUseCaseService;
    @Autowired
    private ChannelOnlineService channelOnlineService;
    @Autowired
    private UidGenerator uidGenerator;
    @Autowired
    private WorkflowService workflowService;
    @Autowired
    private WorkTaskDetailService workTaskDetailService;
    @Autowired
    private WorkTaskApproveRecordService workTaskApproveRecordService;
    @Autowired
    private WorkTaskAssignService workTaskAssignService;

    /*
     * 保证金调整为0,直接生效额度处理公用方法
     *
     * */
    
    @Override
    @Transactional
    public void effectQuotaMethod(QuotaCondition condition, String busType){
        if(BUSINESS_TYPE_NEW_CAR.equals(busType)){
            ChannelRiskInfoTemp risk = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfoTemp>query().lambda().eq(ChannelRiskInfoTemp::getId, condition.getRiskId().toString()));
            //新车保证金调整金额赋值为0(实际保证金=数据库原始保证金+此次保证金调整金额；因为0所以 channelDeposit 不在重新赋值，将保证金调整金额赋值为0即可)
            risk.setMarginTune(BigDecimal.ZERO);
            channelRiskInfoService.updateById(risk);

            List<ChannelQuotaInfoTemp> list = new ArrayList<>();
            //查询签放额度信息
            ChannelQuotaInfoTemp newQuota = getById(condition.getQuotaId().toString());
            BigDecimal oldTempQuota = newQuota.getTempQuota()== null ? BigDecimal.ZERO : newQuota.getTempQuota();
            //临时额度赋值
            BigDecimal tempQuota = condition.getTempQuota() == null ? BigDecimal.ZERO : condition.getTempQuota();
            newQuota.setTempQuota(tempQuota);
            //签放额度调整赋值
            BigDecimal quotaSigning = condition.getQuotaSigning() == null ? BigDecimal.ZERO : condition.getQuotaSigning();
            newQuota.setQuotaSigning(quotaSigning);
            //查询数据库原始签放额度金额
            BigDecimal quotaAmount = newQuota.getQuotaAmount() == null ? BigDecimal.ZERO : newQuota.getQuotaAmount();
            //当前签放额度=数据库已有签放额度+此次追加签放额度
            newQuota.setQuotaAmount(quotaAmount.add(quotaSigning).setScale(2, BigDecimal.ROUND_HALF_UP));
            //当前剩余额度=当前签放额度+当前临时额度-占用额度
            BigDecimal occupiedQuota = newQuota.getOccupiedQuota() == null ? BigDecimal.ZERO : newQuota.getOccupiedQuota();
            newQuota.setSurplusQuota(newQuota.getQuotaAmount().add(newQuota.getTempQuota()).subtract(occupiedQuota).setScale(2, BigDecimal.ROUND_HALF_UP));
            //临时额度有效期
            if(condition.getValidityTermEnd()==null){
                newQuota.setValidityTermEnd(null);
            }else{
                newQuota.setValidityTermEnd(condition.getValidityTermEnd());
            }
            //是否控制额度赋值
            newQuota.setQuotaControlSwitch(condition.getIsLimitPut());
            //签放额度调整归零
            newQuota.setQuotaSigning(BigDecimal.ZERO);
            updateById(newQuota);
            /*记录到渠道日志信息中*/
            if( (condition.getQuotaSigning() == null ? BigDecimal.ZERO : condition.getQuotaSigning()).compareTo(BigDecimal.ZERO) != 0 || (condition.getTempQuotaPut() == null ? BigDecimal.ZERO : condition.getTempQuotaPut()).compareTo(oldTempQuota) != 0 ){
                //临时额度调整和额度调整都不为0
                saveLog(newQuota,quotaAmount);
            }
            list.add(newQuota);
            //查询额度信息
            ChannelQuotaInfoTemp newQuotaPut = getById(condition.getQuotaIdPut().toString());
            BigDecimal oldTempQuotaPut = newQuotaPut.getTempQuota()== null ? BigDecimal.ZERO : newQuotaPut.getTempQuota();
            //临时额度赋值
            BigDecimal tempQuotaPut = condition.getTempQuotaPut() == null ? BigDecimal.ZERO : condition.getTempQuotaPut();
            newQuotaPut.setTempQuota(tempQuotaPut);
            //签放额度调整赋值
            BigDecimal quotaSigningPut = condition.getQuotaSigningPut() == null ? BigDecimal.ZERO : condition.getQuotaSigningPut();
            newQuotaPut.setQuotaSigning(quotaSigningPut);
            //获取数据原始先放后抵额度信息
            BigDecimal quotaAmountPut = newQuotaPut.getQuotaAmount() == null ? BigDecimal.ZERO : newQuotaPut.getQuotaAmount();
            //当前先放后抵额度=数据库已有先放额度额度+此次追加先放后抵额度
            newQuotaPut.setQuotaAmount(quotaAmountPut.add(quotaSigningPut).setScale(2, BigDecimal.ROUND_HALF_UP));
            //当前剩余额度=当前签放额度+当前临时额度-占用额度
            BigDecimal occupiedQuotaPut = newQuotaPut.getOccupiedQuota() == null ? BigDecimal.ZERO : newQuotaPut.getOccupiedQuota();
            newQuotaPut.setSurplusQuota(newQuotaPut.getQuotaAmount().add(newQuotaPut.getTempQuota()).subtract(occupiedQuotaPut).setScale(2, BigDecimal.ROUND_HALF_UP));
            if(condition.getValidityTermEndPut()==null){
                newQuotaPut.setValidityTermEnd(null);
            }else{
                newQuotaPut.setValidityTermEnd(condition.getValidityTermEndPut());
            }
            //签放额度调整归零
            newQuotaPut.setQuotaSigning(BigDecimal.ZERO);
            //是否控制额度赋值
            newQuotaPut.setQuotaControlSwitch(condition.getIsLimitPledge());
            updateById(newQuotaPut);
            /*记录到渠道日志信息中*/
            if( (condition.getQuotaSigningPut() == null ? BigDecimal.ZERO : condition.getQuotaSigningPut()).compareTo(BigDecimal.ZERO) != 0 || (condition.getTempQuotaPut() == null ? BigDecimal.ZERO : condition.getTempQuotaPut()).compareTo(oldTempQuotaPut) != 0 ){
                //临时额度调整和额度调整都不为0
                saveLog(newQuotaPut,quotaAmountPut);
            }
            list.add(newQuotaPut);
            ChannelQuotaInfoVo vo = new ChannelQuotaInfoVo();
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("clientId", channelConfig.getCaseClientId());
            headers.put("clientSecret", channelConfig.getCaseClientSecret());
            vo.setQuota(list);
            vo.setRiskInfo(risk);
            channelUseCaseService.upQuota(vo,headers);
        }else{
            ChannelRiskInfoTemp riskOld = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfoTemp>query().lambda().eq(ChannelRiskInfoTemp::getId, condition.getRiskIdOld()));
            //二手车保证金调整金额赋值为0(实际保证金=数据库原始保证金+此次保证金调整金额；因为0所以 channelDeposit 不在重新赋值，将保证金调整金额赋值为0即可)
            riskOld.setMarginTune(BigDecimal.ZERO);
            channelRiskInfoService.updateById(riskOld);

            List<ChannelQuotaInfoTemp> list = new ArrayList<>();
            //查询签放额度信息
            ChannelQuotaInfoTemp oldQuota = getById(condition.getQuotaIdOld().toString());
            BigDecimal oldTempQuota = oldQuota.getTempQuota()== null ? BigDecimal.ZERO : oldQuota.getTempQuota();
            //临时额度赋值
            BigDecimal tempQuotaOld = condition.getTempQuotaOld() == null ? BigDecimal.ZERO : condition.getTempQuotaOld();
            oldQuota.setTempQuota(tempQuotaOld);
            //签放额度赋值
            BigDecimal  quotaSigningOld = condition.getQuotaSigningOld() == null ? BigDecimal.ZERO : condition.getQuotaSigningOld();
            oldQuota.setQuotaSigning(quotaSigningOld);
            //查询数据库原始签放额度金额
            BigDecimal quotaAmount = oldQuota.getQuotaAmount() == null ? BigDecimal.ZERO : oldQuota.getQuotaAmount();
            //当前签放额度=数据库已有签放额度+此次追加签放额度
            oldQuota.setQuotaAmount(quotaAmount.add(quotaSigningOld).setScale(2, BigDecimal.ROUND_HALF_UP));
            //当前剩余额度=当前签放额度+当前临时额度-占用额度
            BigDecimal occupiedQuotaOld = oldQuota.getOccupiedQuota() == null ? BigDecimal.ZERO : oldQuota.getOccupiedQuota();
            oldQuota.setSurplusQuota(oldQuota.getQuotaAmount().add(oldQuota.getTempQuota()).subtract(occupiedQuotaOld).setScale(2, BigDecimal.ROUND_HALF_UP));
            //临时额度有效期
            if(condition.getValidityTermEndOld()==null){
                oldQuota.setValidityTermEnd(null);
            }else{
                oldQuota.setValidityTermEnd(condition.getValidityTermEndOld());
            }
            //签放额度调整归零
            oldQuota.setQuotaSigning(BigDecimal.ZERO);
            //是否控制额度赋值
            oldQuota.setQuotaControlSwitch(condition.getIsLimitPutOld());
            updateById(oldQuota);
            /*记录到渠道日志信息中*/
            if( (condition.getQuotaSigningOld() == null ? BigDecimal.ZERO : condition.getQuotaSigningOld()).compareTo(BigDecimal.ZERO) != 0 || (condition.getTempQuotaOld() == null ? BigDecimal.ZERO : condition.getTempQuotaOld()).compareTo(oldTempQuota) != 0 ){
                //临时额度调整和额度调整都不为0
                saveLog(oldQuota,quotaAmount);
            }
            list.add(oldQuota);
            //查询先放后抵额度信息
            ChannelQuotaInfoTemp oldQuotaPut = getById(condition.getQuotaIdPutOld().toString());
            BigDecimal oldTempQuotaPut = oldQuotaPut.getTempQuota()== null ? BigDecimal.ZERO : oldQuotaPut.getTempQuota();
            //此次临时额度赋值
            BigDecimal  tempQuotaPutOld = condition.getTempQuotaPutOld() == null ? BigDecimal.ZERO : condition.getTempQuotaPutOld();
            oldQuotaPut.setTempQuota(tempQuotaPutOld);
            //此次签放额度赋值
            BigDecimal  quotaSigningPutOld = condition.getQuotaSigningPutOld() == null ? BigDecimal.ZERO : condition.getQuotaSigningPutOld();
            oldQuotaPut.setQuotaSigning(quotaSigningPutOld);
            //获取数据原始先放后抵额度信息
            BigDecimal quotaAmountPut = oldQuotaPut.getQuotaAmount() == null ? BigDecimal.ZERO : oldQuotaPut.getQuotaAmount();
            //当前先放后抵额度=数据库已有先放额度额度+此次追加先放后抵额度
            oldQuotaPut.setQuotaAmount(quotaAmountPut.add(quotaSigningPutOld).setScale(2, BigDecimal.ROUND_HALF_UP));
            //当前剩余额度=当前签放额度+当前临时额度-占用额度
            BigDecimal occupiedQuotaOldPut = oldQuotaPut.getOccupiedQuota() == null ? BigDecimal.ZERO : oldQuotaPut.getOccupiedQuota();
            oldQuotaPut.setSurplusQuota(oldQuotaPut.getQuotaAmount().add(oldQuotaPut.getTempQuota()).subtract(occupiedQuotaOldPut).setScale(2, BigDecimal.ROUND_HALF_UP));
            //二手车先签后抵有效期赋值
            if(condition.getValidityTermEndPutOld()==null){
                oldQuotaPut.setValidityTermEnd(null);
            }else{
                oldQuotaPut.setValidityTermEnd(condition.getValidityTermEndPutOld());
            }
            //签放额度调整归零
            oldQuotaPut.setQuotaSigning(BigDecimal.ZERO);
            //是否控制额度赋值
            oldQuota.setQuotaControlSwitch(condition.getIsLimitPledgeOld());
            updateById(oldQuotaPut);
            /*记录到渠道日志信息中*/
            if( (condition.getTempQuotaPutOld() == null ? BigDecimal.ZERO : condition.getTempQuotaPutOld()).compareTo(BigDecimal.ZERO) != 0 || (condition.getTempQuotaPutOld() == null ? BigDecimal.ZERO : condition.getTempQuotaPutOld()).compareTo(oldTempQuotaPut) != 0 ){
                //临时额度调整和额度调整都不为0
                saveLog(oldQuotaPut,quotaAmountPut);
            }
            list.add(oldQuotaPut);
            ChannelQuotaInfoVo vo = new ChannelQuotaInfoVo();
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("clientId", channelConfig.getCaseClientId());
            headers.put("clientSecret", channelConfig.getCaseClientSecret());
            vo.setQuota(list);
            vo.setRiskInfo(riskOld);
            channelUseCaseService.upQuota(vo, headers);
        }
    }

    /*
     * 保证金调整不为0,额度处理提交工作流公用方法
     *
     * */
    @Override
    @Transactional
    public boolean QuotaToWorkFlowMethod(QuotaCondition condition,String busType) throws JsonProcessingException {

        if(BUSINESS_TYPE_NEW_CAR.equals(busType)){
            ChannelRiskInfoTemp risk = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfoTemp>query().lambda().eq(ChannelRiskInfoTemp::getId, condition.getRiskId().toString()));
            if (risk != null) {
                //保证金调整金额赋值
                risk.setMarginTune(condition.getMarginTune());
                channelRiskInfoService.updateById(risk);
                //查询签放额度信息
                ChannelQuotaInfoTemp newQuota = getById(condition.getQuotaId().toString());
                //签放额度调整赋值
                BigDecimal quotaSigning = condition.getQuotaSigning() == null ? BigDecimal.ZERO : condition.getQuotaSigning();
                newQuota.setQuotaSigning(quotaSigning);
                //临时额度调整赋值
                BigDecimal tempQuota = condition.getTempQuota() == null ? BigDecimal.ZERO : condition.getTempQuota();
                newQuota.setTempQuotaAdjust(tempQuota);
                //临时额度有效期调整赋值
                newQuota.setValidityTermEndAdjust(condition.getValidityTermEnd());
                newQuota.setQuotaControlSwitchAdjust(condition.getIsLimitPut());
                updateById(newQuota);

                //查询先放后抵额度信息
                ChannelQuotaInfoTemp newQuotaPut = getById(condition.getQuotaIdPut().toString());
                //签放额度调整赋值
                BigDecimal quotaSigningPut = condition.getQuotaSigningPut() == null ? BigDecimal.ZERO : condition.getQuotaSigningPut();
                newQuotaPut.setQuotaSigning(quotaSigningPut);
                //此次临时额度调整赋值
                BigDecimal tempQuotaPut = condition.getTempQuotaPut() == null ? BigDecimal.ZERO : condition.getTempQuotaPut();
                newQuotaPut.setTempQuotaAdjust(tempQuotaPut);
                //临时额度有效期调整赋值
                newQuotaPut.setValidityTermEndAdjust(condition.getValidityTermEndPut());
                newQuota.setQuotaControlSwitchAdjust(condition.getIsLimitPledge());
                updateById(newQuotaPut);
                //开始新车额度调整工作流
                //获取渠道基本信息
                ChannelBaseInfoTemp baseInfoTemp = channelOnlineService.getById(risk.getChannelId());
                //发起新车额度审核工作流
                return  quotaWorkflow(baseInfoTemp,BUSINESS_TYPE_NEW_CAR);
            }
        }else{
            ChannelRiskInfoTemp riskOld = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfoTemp>query().lambda().eq(ChannelRiskInfoTemp::getId, condition.getRiskIdOld().toString()));
            if (riskOld != null) {
                //二手车保证金调整金额赋值
                riskOld.setMarginTune(condition.getMarginTuneOld());
                channelRiskInfoService.updateById(riskOld);
                //查询签放额度信息
                ChannelQuotaInfoTemp oldQuota = getById(condition.getQuotaIdOld().toString());
                //签放额度调整赋值
                BigDecimal quotaSigningOld = condition.getQuotaSigningOld() == null ? BigDecimal.ZERO : condition.getQuotaSigningOld();
                oldQuota.setQuotaSigning(quotaSigningOld);
                //临时额度调整赋值
                BigDecimal tempQuotaOld = condition.getTempQuotaOld() == null ? BigDecimal.ZERO : condition.getTempQuotaOld();
                oldQuota.setTempQuotaAdjust(tempQuotaOld);
                //临时额度有效期调整赋值
                oldQuota.setValidityTermEndAdjust(condition.getValidityTermEndOld());
                oldQuota.setQuotaControlSwitchAdjust(condition.getIsLimitPutOld());
                updateById(oldQuota);
                //二手车先签后抵
                ChannelQuotaInfoTemp oldQuotaPut = getById(condition.getQuotaIdPutOld().toString());
                //签放额度调整赋值
                BigDecimal quotaSigningPutOld = condition.getQuotaSigningPutOld() == null ? BigDecimal.ZERO : condition.getQuotaSigningPutOld();
                oldQuotaPut.setQuotaSigning(quotaSigningPutOld);
                //此次临时额度调整赋值
                BigDecimal tempQuotaPutOld = condition.getTempQuotaPutOld() == null ? BigDecimal.ZERO : condition.getTempQuotaPutOld();
                oldQuotaPut.setTempQuotaAdjust(tempQuotaPutOld);
                //临时额度有效期调整赋值
                oldQuotaPut.setValidityTermEndAdjust(condition.getValidityTermEndPutOld());
                oldQuota.setQuotaControlSwitchAdjust(condition.getIsLimitPledgeOld());
                updateById(oldQuotaPut);
                //二手车额度维护开始工作流
                //先获取渠道基本信息
                ChannelBaseInfoTemp baseInfoTemp = channelOnlineService.getById(riskOld.getChannelId());
                //发起二手车额度审核工作流
                return quotaWorkflow(baseInfoTemp,BUSINESS_TYPE_OLD_CAR);
            }
        }
        return false;
    }


    /*保存到渠道上线日志方法*/
    @Override
    @Transactional
    public void saveLog(ChannelQuotaInfoTemp quotaInfo, BigDecimal beforeChangeQuota ){

        /*记录到渠道日志信息中*/
        String businessType = quotaInfo.getBusinessType();
        String quotaType = quotaInfo.getQuotaType();
        ArchivesLogInfoCondition log = new ArchivesLogInfoCondition();
        log.setChannelId(quotaInfo.getChannelId());
        if(BUSINESS_TYPE_NEW_CAR.equals(businessType)) {
            businessType = "新车";
        } else {
            businessType = "二手车";
        }
        if(SIGN_QUOTA.equals(quotaType)){
            quotaType = "签放";
        }else{
            quotaType = "先放后抵";
        }
        log.setEventName(businessType +quotaType +"额度修改" );
        log.setDescription("");
        if(quotaInfo.getValidityTermEnd() != null){
            String amountLog = businessType + quotaType +"额度由:"+ beforeChangeQuota + "变更为:" +  quotaInfo.getQuotaAmount();
            String tempLog = businessType + quotaType +"临时额度变更为:"+quotaInfo.getTempQuota();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String tempEnd = businessType + quotaType +"临时额度到期时间变更为:"+sdf.format(quotaInfo.getValidityTermEnd());
            log.setDescription( amountLog +"," +tempLog +","+ tempEnd);
        }else{
            String amountLog = businessType + quotaType +"额度由:"+ beforeChangeQuota + "变更为:" +  quotaInfo.getQuotaAmount();
            log.setDescription( amountLog);
        }
        channelArchivesInfoService.saveQuotaChangeArchivesInfo(log);
    }

    @Override
    public void handleExcelImport(MultipartFile file)  throws Exception{

        XSSFWorkbook xssFWorkbook = new XSSFWorkbook(file.getInputStream());
        List<ChannelQuotaInfoTemp> channelQuotaInfoTempList = new ArrayList<>();

        /**  解析  **/
        channelQuotaInfoTempList = this.importExcelFileForXss(xssFWorkbook);
        //同步案件服务用
        List<ChannelQuotaInfoTemp> list = new ArrayList<>();

        //拿到数据之后做处理
        if(channelQuotaInfoTempList.size() > 0 ){
            for (ChannelQuotaInfoTemp temp : channelQuotaInfoTempList){
                ChannelQuotaInfoTemp one = getOne(Wrappers.<ChannelQuotaInfoTemp>query().lambda()
                        .eq(ChannelQuotaInfoTemp::getBusinessType, temp.getBusinessType())
                        .eq(ChannelQuotaInfoTemp::getChannelId, temp.getChannelId())
                        .eq(ChannelQuotaInfoTemp::getQuotaType, temp.getQuotaType())
                );
                //临时额度赋值
                BigDecimal tempQuota = temp.getTempQuota() == null ? BigDecimal.ZERO : temp.getTempQuota();
                one.setTempQuota(tempQuota);
                //签放额度调整赋值
                BigDecimal quotaSigning = temp.getQuotaSigning() == null ? BigDecimal.ZERO : temp.getQuotaSigning();
                one.setQuotaSigning(quotaSigning);
                //查询数据库原始签放额度金额
                BigDecimal quotaAmount = one.getQuotaAmount() == null ? BigDecimal.ZERO : one.getQuotaAmount();
                //当前签放额度=数据库已有签放额度+此次追加签放额度
                one.setQuotaAmount(quotaAmount.add(quotaSigning).setScale(2, BigDecimal.ROUND_HALF_UP));
                //当前剩余额度=当前签放额度+当前临时额度-占用额度
                BigDecimal occupiedQuota = one.getOccupiedQuota() == null ? BigDecimal.ZERO : one.getOccupiedQuota();
                one.setSurplusQuota(one.getQuotaAmount().add(one.getTempQuota()).subtract(occupiedQuota).setScale(2, BigDecimal.ROUND_HALF_UP));
                //临时额度有效期
                if(temp.getValidityTermEnd()==null){
                    one.setValidityTermEnd(null);
                }else{
                    one.setValidityTermEnd(temp.getValidityTermEnd());
                }
                //签放额度调整归零
                one.setQuotaSigning(BigDecimal.ZERO);
                updateById(one);
                list.add(one);
                /*记录到渠道日志信息中*/
                saveLog(one,quotaAmount);
            }
            //同步案件服务
                ChannelQuotaInfoVo vo = new ChannelQuotaInfoVo();
                Map<String, String> headers = new HashMap<String, String>();
                headers.put("clientId", channelConfig.getCaseClientId());
                headers.put("clientSecret", channelConfig.getCaseClientSecret());
                vo.setQuota(list);
                channelUseCaseService.upQuota(vo,headers);

        }

    }



    private List<ChannelQuotaInfoTemp>  importExcelFileForXss(XSSFWorkbook xssFWorkbook) throws Exception {
        List<ChannelQuotaInfoTemp> channelQuotaInfoTempList = new ArrayList<>();

        /**  创建工作表  **/
        Sheet sheet = xssFWorkbook.getSheetAt(0);
        int end = sheet.getLastRowNum();
        for (int i = 1; i <= end; i++) {
            /**  逐行解析 **/
            ChannelQuotaInfoTemp channelQuotaInfoTemp = this.praseRow(sheet.getRow(i),i);
            /**  数据归集 **/
            channelQuotaInfoTempList.add(channelQuotaInfoTemp);
        }
        return channelQuotaInfoTempList;
    }


    private ChannelQuotaInfoTemp praseRow(Row row, int i) throws Exception{
        ChannelQuotaInfoTemp channelQuotaInfoTemp = new ChannelQuotaInfoTemp();
        //int j= 1;
        int j= 0;
        /**  合作商代码   **/
        String channelCode;
        if ( CellType.STRING.equals(row.getCell(j).getCellTypeEnum())){
            channelCode = row.getCell(j).getRichStringCellValue().toString();
            if (StringUtils.isEmpty(channelCode)){
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列为空，请检查");
            }
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为文本");
        }
        //根据合作商代码查出来合作商id
        ChannelBaseInfoTemp baseInfoTemp = channelOnlineService.getOne(Wrappers.<ChannelBaseInfoTemp>query().lambda().eq(ChannelBaseInfoTemp::getChannelCode, channelCode));
        if(baseInfoTemp == null){
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列合作商代码错误,系统中不存在此合作商,请检查!");
        }
        channelQuotaInfoTemp.setChannelId(baseInfoTemp.getId());
        j++;

        /**  业务类型   **/
        String businessType;
        if ( CellType.STRING.equals(row.getCell(j).getCellTypeEnum())){
            businessType = row.getCell(j).getRichStringCellValue().toString();
            if (StringUtils.isEmpty(businessType)){
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列为空，请检查");
            }
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为文本");
        }
        if("新车".equals(businessType)){
            businessType = BUSINESS_TYPE_NEW_CAR;
        }else if("二手车".equals(businessType)){
            businessType = BUSINESS_TYPE_OLD_CAR;
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列业务类型错误,业务类型只能为新车或二手车");
        }
        channelQuotaInfoTemp.setBusinessType(businessType);
        j++;

        /**  额度类型   **/
        String quotaType;
        if ( CellType.STRING.equals(row.getCell(j).getCellTypeEnum())){
            quotaType = row.getCell(j).getRichStringCellValue().toString();
            if (StringUtils.isEmpty(quotaType)){
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列为空，请检查");
            }
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为文本");
        }
        if("签放".equals(quotaType)){
            quotaType = SIGN_QUOTA;
        }else if("先放后抵".equals(quotaType)){
            quotaType = BEFORE_LOAN;
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列业务放款类型错误,放款类型只能为签放或先放后抵");
        }
        channelQuotaInfoTemp.setQuotaType(quotaType);
        j++;

        /**  是否控制额度   **/
        String quotaControlSwitch;
        if ( CellType.STRING.equals(row.getCell(j).getCellTypeEnum())){
            quotaControlSwitch = row.getCell(j).getRichStringCellValue().toString();
            if (StringUtils.isEmpty(quotaControlSwitch)){
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列为空，请检查");
            }
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为文本");
        }
        if("是".equals(quotaControlSwitch)){
            quotaControlSwitch = TYPE_YES;
        }else if("否".equals(quotaControlSwitch)){
            quotaControlSwitch = TYPE_NO;
        }else{
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列是否控制额度错误,是否控制额度只能为是或否");
        }
        channelQuotaInfoTemp.setQuotaControlSwitch(quotaControlSwitch);
        j++;
       // j++;  //额度无需验证

        /**  额度调整   **/
        double quotaSigningDouble = 0;
        if(row.getCell(j) != null && row.getCell(j).getCellType() != Cell.CELL_TYPE_BLANK){
            if ( CellType.NUMERIC.equals(row.getCell(j).getCellTypeEnum())){
                quotaSigningDouble = row.getCell(j).getNumericCellValue();
            }else{
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为数字类型");
            }
        }else if((row.getCell(j) == null ||row.getCell(j).getCellType() == Cell.CELL_TYPE_BLANK)  &&  TYPE_YES.equals(quotaControlSwitch)){
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列为空，请检查");
        }

        channelQuotaInfoTemp.setQuotaSigning(new BigDecimal(quotaSigningDouble));
        j++;

        /**  临时额度   **/
        double tempQuotaDouble = 0;
        if(row.getCell(j) != null && row.getCell(j).getCellType() != Cell.CELL_TYPE_BLANK){
            if ( CellType.NUMERIC.equals(row.getCell(j).getCellTypeEnum())){
                tempQuotaDouble = row.getCell(j).getNumericCellValue();
            }else{
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为数字类型");
            }
        }
        channelQuotaInfoTemp.setTempQuota(new BigDecimal(tempQuotaDouble));
        j++;


        /**  临时额度有效期  **/
        Date validityTermEnd = null;

        if(row.getCell(j) != null && row.getCell(j).getCellType() != Cell.CELL_TYPE_BLANK){

            if ( CellType.NUMERIC.equals(row.getCell(j).getCellTypeEnum())){
                 validityTermEnd = row.getCell(j).getDateCellValue();
            }else{
                throw new Exception("第"+(i+1)+"行第"+(j+1)+"列格式格式错误,需要格式为日期,日期格式为yyyy-MM-dd");
            }
        }else if((row.getCell(j) == null ||row.getCell(j).getCellType() == Cell.CELL_TYPE_BLANK)  && tempQuotaDouble != 0){
            throw new Exception("第"+(i+1)+"行第"+(j+1)+"列为空，请检查");
        }
        channelQuotaInfoTemp.setValidityTermEnd(validityTermEnd);
        return channelQuotaInfoTemp;
    }


    /**
     * 渠道额度维护提交工作流公用方法
     */
    public boolean quotaWorkflow(ChannelBaseInfoTemp baseInfo,String busType) throws JsonProcessingException {

        //先查一下是否已经在流程
        List<WorkTaskDetail> workTaskDetails = workTaskDetailService.list(Wrappers.<WorkTaskDetail>query().lambda()
                .eq(WorkTaskDetail::getBusinessKey,baseInfo.getId())
                .eq(WorkTaskDetail::getBusinessType,busType)
        );
        if(workTaskDetails.size() > 0){
            for (WorkTaskDetail detail :workTaskDetails){
                String bizDataId = detail.getBizDataId();
                List<WorkTaskAssign> workTaskAssigns = workTaskAssignService.list(Wrappers.<WorkTaskAssign>query().lambda()
                        .eq(WorkTaskAssign::getBizDataId, bizDataId)
                        .eq(WorkTaskAssign::getAfsFlowKey,ChannelAfsFlowEnum.CHANNEL_QUOTA_NEW)
                );
                if(workTaskAssigns.size() > 0){
                    return false;
                }
            }
        }

        //判断拥有新车角色权限、且(渠道从未发起过新车审批流程)
        if (BUSINESS_TYPE_NEW_CAR.equals(busType)) {
            //发起新车额度维护审批流程
            //   if (workTaskDetail == null) {
            StartFlowRequest startFlowNew = new StartFlowRequest();
            //枚举新车渠道额度维护
            startFlowNew.setAfsFlowKey(AfsEnumUtil.key(ChannelAfsFlowEnum.CHANNEL_QUOTA_NEW));
            startFlowNew.setBizDataId(uidGenerator.getUID() + "");
            //枚举新车渠道额度维护
            startFlowNew.setFlowName((StringUtils.isEmpty(baseInfo.getChannelFullName())?"":(baseInfo.getChannelFullName())+"-")+AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_QUOTA_NEW));
            ObjectMapper mapper = new ObjectMapper();
            String json = null;
            try {
                json = mapper.writeValueAsString(baseInfo);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            JSONObject cancelJson = JSONObject.parseObject(json);
            //业务类型:新车
            cancelJson.put(AfsEnumUtil.key(ChannelAfsFlowEnum.BUSINESS_TYPE), BUSINESS_TYPE_NEW_CAR);
            workflowService.startWorkFlow(startFlowNew, cancelJson);

            //保存业务相关数据、用户前端逻辑判断
            WorkTaskDetail detail = new WorkTaskDetail();
            detail.setBizDataId(startFlowNew.getBizDataId());
            //新车
            detail.setBusinessType(BUSINESS_TYPE_NEW_CAR);
            detail.setName(baseInfo.getChannelFullName());
            detail.setFlowName(AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_QUOTA_NEW));
            //渠道id绑定
            detail.setBusinessKey(baseInfo.getId());
            workTaskDetailService.save(detail);
            workTaskApproveRecordService.startSave(AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_QUOTA_NEW), startFlowNew.getBizDataId());

            // }
        }
        //判断拥有二手车角色权限、且(渠道从未发起过二手车审批流程)
        if (BUSINESS_TYPE_OLD_CAR.equals(busType)) {
            //发起二手车额度维护审批流程
            StartFlowRequest startFlowOld = new StartFlowRequest();
            //枚举二手车渠道额度维护
            startFlowOld.setAfsFlowKey(AfsEnumUtil.key(ChannelAfsFlowEnum.CHANNEL_QUOTA_OLD));
            startFlowOld.setBizDataId(uidGenerator.getUID() + "");
            //枚举二手车渠道额度维护
            startFlowOld.setFlowName((StringUtils.isEmpty(baseInfo.getChannelFullName())?"":(baseInfo.getChannelFullName())+"-")+AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_QUOTA_OLD));
            ObjectMapper mapper = new ObjectMapper();
            String json = null;
            try {
                json = mapper.writeValueAsString(baseInfo);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            JSONObject cancelJson = JSONObject.parseObject(json);
            //业务类型:二手车
            cancelJson.put(AfsEnumUtil.key(ChannelAfsFlowEnum.BUSINESS_TYPE), BUSINESS_TYPE_OLD_CAR);
            workflowService.startWorkFlow(startFlowOld, cancelJson);

            //保存业务相关数据、用户前端逻辑判断
            WorkTaskDetail detail = new WorkTaskDetail();
            detail.setBizDataId(startFlowOld.getBizDataId());
            //二手车
            detail.setBusinessType(BUSINESS_TYPE_OLD_CAR);
            detail.setName(baseInfo.getChannelFullName());
            detail.setFlowName(AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_QUOTA_OLD));
            //渠道id绑定
            detail.setBusinessKey(baseInfo.getId());
            workTaskDetailService.save(detail);
            workTaskApproveRecordService.startSave(AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_QUOTA_OLD), startFlowOld.getBizDataId());
        }
        return true;

    }

    @Override
    public void handleCsvImport(MultipartFile file)  throws Exception{
        CSVReader csvReader = null;
            csvReader = new CSVReader(new InputStreamReader(new DataInputStream(file.getInputStream()), "utf-8"));
            String [] head =  csvReader.readNext();//去除表头
            if(!"渠道名称".equals(head[0]) && !"渠道代码".equals(head[1])){
                csvReader = new CSVReader(new InputStreamReader(new DataInputStream(file.getInputStream()), "gbk"));
                String [] head2 =  csvReader.readNext();//去除表头
                if(!"渠道名称".equals(head2[0]) && !"渠道代码".equals(head2[1])){
                    try {
                        if (csvReader != null) {
                            csvReader.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    throw new AfsBaseException("请勿修改表头字段名称!");
                }
            }
            try {
            List<ChannelQuotaInfoTemp> arrays = new ArrayList<>();
            String [] strs = csvReader.readNext();
            while(null != strs) {
                ChannelQuotaInfoTemp channelQuotaInfoTemp = new ChannelQuotaInfoTemp();
                //合作商id
                if(strs[1] !="" || strs[1] !=null){
                    channelQuotaInfoTemp.setChannelId(channelOnlineService.getOne(Wrappers.<ChannelBaseInfoTemp>query().lambda().eq(ChannelBaseInfoTemp::getChannelCode, strs[1])).getId());
                }else{
                    strs = csvReader.readNext();
                    continue;
                }
                //业务类型
                if(!"新车".equals(strs[2]) && !"二手车".equals(strs[2])){
                    strs = csvReader.readNext();
                    continue;
                }else{
                    channelQuotaInfoTemp.setBusinessType("新车".equals(strs[2]) ? "01" : "02");
                }
                //额度类型
                if(!"签放".equals(strs[3]) && !"先放后抵".equals(strs[3])){
                    strs = csvReader.readNext();
                    continue;
                }else{
                    channelQuotaInfoTemp.setQuotaType("签放".equals(strs[3]) ? "1" : "2");
                }
                //额度是否控制
                if(!"是".equals(strs[4]) && !"否".equals(strs[4])){
                    strs = csvReader.readNext();
                    continue;
                }else{
                    channelQuotaInfoTemp.setQuotaControlSwitch("是".equals(strs[4]) ? "1" : "0");
                }
                //额度调整
                try {
                    channelQuotaInfoTemp.setQuotaSigning(new BigDecimal("".equals(strs[6]) ? "0" : strs[6]));
                } catch (Exception e) {
                    strs = csvReader.readNext();
                    continue;
                }
                //临时额度调整
                try {
                    channelQuotaInfoTemp.setTempQuota(new BigDecimal("".equals(strs[7]) ? "0" : strs[7]));
                } catch (Exception e) {
                    strs = csvReader.readNext();
                    continue;
                }
                //临时额度有效期
                if(channelQuotaInfoTemp.getTempQuota().compareTo(BigDecimal.ZERO) != 0 && "".equals(strs[8])){
                    strs = csvReader.readNext();
                    continue;
                }else if(!"".equals(strs[8]) && channelQuotaInfoTemp.getTempQuota().compareTo(BigDecimal.ZERO) != 0){
                    try {
                        channelQuotaInfoTemp.setValidityTermEnd(new SimpleDateFormat("yyyy/MM/dd").parse(strs[8]));
                    } catch (Exception e) {
                        strs = csvReader.readNext();
                        continue;
                    }
                }
                //加入list处理业务
                arrays.add(channelQuotaInfoTemp);
                strs = csvReader.readNext();
            }
            //处理业务
            handleCsvImport(arrays);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (csvReader != null) {
                    csvReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public void handleCsvImport(List<ChannelQuotaInfoTemp> channelQuotaInfoTempList)  throws Exception{

        /**  解析  **/
        //同步案件服务用
        List<ChannelQuotaInfoTemp> list = new ArrayList<>();

        //拿到数据之后做处理
        if(channelQuotaInfoTempList.size() > 0 ){
            for (ChannelQuotaInfoTemp temp : channelQuotaInfoTempList){
                ChannelQuotaInfoTemp one = getOne(Wrappers.<ChannelQuotaInfoTemp>query().lambda()
                        .eq(ChannelQuotaInfoTemp::getBusinessType, temp.getBusinessType())
                        .eq(ChannelQuotaInfoTemp::getChannelId, temp.getChannelId())
                        .eq(ChannelQuotaInfoTemp::getQuotaType, temp.getQuotaType())
                );
                //临时额度赋值
                BigDecimal tempQuota = temp.getTempQuota() == null ? BigDecimal.ZERO : temp.getTempQuota();
                one.setTempQuota(tempQuota);
                //签放额度调整赋值
                BigDecimal quotaSigning = temp.getQuotaSigning() == null ? BigDecimal.ZERO : temp.getQuotaSigning();
                one.setQuotaSigning(quotaSigning);
                //查询数据库原始签放额度金额
                BigDecimal quotaAmount = one.getQuotaAmount() == null ? BigDecimal.ZERO : one.getQuotaAmount();
                //当前签放额度=数据库已有签放额度+此次追加签放额度
                one.setQuotaAmount(quotaAmount.add(quotaSigning).setScale(2, BigDecimal.ROUND_HALF_UP));
                //当前剩余额度=当前签放额度+当前临时额度-占用额度
                BigDecimal occupiedQuota = one.getOccupiedQuota() == null ? BigDecimal.ZERO : one.getOccupiedQuota();
                one.setSurplusQuota(one.getQuotaAmount().add(one.getTempQuota()).subtract(occupiedQuota).setScale(2, BigDecimal.ROUND_HALF_UP));
                //临时额度有效期
                if(temp.getValidityTermEnd()==null){
                    one.setValidityTermEnd(null);
                }else{
                    one.setValidityTermEnd(temp.getValidityTermEnd());
                }
                //是否控制额度赋值
                one.setQuotaControlSwitch(temp.getQuotaControlSwitch());
                //签放额度调整归零
                one.setQuotaSigning(BigDecimal.ZERO);
                updateById(one);
                list.add(one);
                /*记录到渠道日志信息中*/
                saveLog(one,quotaAmount);
            }
            //同步案件服务
            ChannelQuotaInfoVo vo = new ChannelQuotaInfoVo();
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("clientId", channelConfig.getCaseClientId());
            headers.put("clientSecret", channelConfig.getCaseClientSecret());
            vo.setQuota(list);
            channelUseCaseService.upQuota(vo,headers);
        }

    }



}
